// ActionScript file
package
{
	import AStar.*;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.PixelSnapping;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.GlowFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.URLRequest;
	import flash.text.TextField;
	import flash.utils.Dictionary;
	import flash.utils.getTimer;
	
	
	public class Scene extends Sprite
	{
		public var sceneRoot:Sprite = new Sprite();
		public var mesh:Sprite = new Sprite();
		public var blocks:Sprite = new Sprite();
		public var alphaPts:Sprite = new Sprite();		
		
		//默认的地图图案
		[Embed(source="MiniMap.jpg")]
		public var DefaultBackgroud:Class;
			
		public var bg:BitmapData;
		public var bm:Bitmap;
					
		//可视范围中心点
		private var _viewPoint:Point = new Point(); 
		
		private var _imageToLoad:Array = new Array();
		private var _imagePos:Point = new Point();
		
		//记录切片是否已经加载过
		private var _imageStatus:Array = new Array();
		
		private var rect:Rectangle = new Rectangle(0, 0, GameGlobals.SLICE_WIDTH, GameGlobals.SLICE_HEIGHT);
		
		private var stg:Stage;
		
		//网格大小
		public static  var gridWidth:int = 30;
		public static  var gridHeight:int = 30;
		
		//网格数组
		private var grids:Grid;
		
		//定点虚化数组
		private var alphaPointArray:Array;
		
		//是否处于设置阻挡点状态
		public var bSetBlock:Boolean = false;
			
		//是否处于设置虚化点状态
		public var bSetAlpha:Boolean = false;
		
		private var lastLogicX:uint = 0;
		private var lastLogicY:uint = 0;
		
		public var bBorderLimit:Boolean = true;
		
		public function get viewPoint():Point
		{
			return _viewPoint;
		}
		
		public function set viewPoint(vp:Point):void
		{
			_viewPoint.x = vp.x;
			_viewPoint.y = vp.y;
		}		
		
		public function Scene(_stg:Stage)
		{		
			Init();	
			
			stg = _stg;
			
			stg.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
			stg.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
			stg.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);			
			stg.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			
			//监听主角移动事件
			stg.addEventListener(GameEvent.HERO_MOVE, onHeroMove)
		}
		
		public function Load():void
		{
			MoveTo(_viewPoint.x, _viewPoint.y);
		}
		
		public function onHeroMove(e:GameEvent):void
		{
			var posX:Number = e.posX;
			var posY:Number = e.posY;
			
			MoveTo(posX, posY);
		}
		
		public function Init():void
		{	
			sceneRoot.x = 0;
			sceneRoot.y = 0;
			addChild(sceneRoot);
					
			bg = new BitmapData(GameGlobals.SLICE_WIDTH*GameGlobals.TOTAL_SLICE_COL_NUM,
				GameGlobals.SLICE_HEIGHT*GameGlobals.TOTAL_SLICE_ROW_NUM, true, 0xFFFFFF);
		
			
			var tmp:BitmapData = (new DefaultBackgroud() as Bitmap).bitmapData;						
						
			//将迷你地图放大为实际地图
			var mtx:Matrix = new Matrix(8, 0, 0, 8);
			bg.draw(tmp, mtx);
			
			bm = new Bitmap(bg);
			bm.x = 0;
			bm.y = 0;
			sceneRoot.addChild(bm);	
			
			for(var i:int = 0; i < GameGlobals.TOTAL_SLICE_ROW_NUM; i++)
			{
				var tmpArray:Array = new Array(GameGlobals.TOTAL_SLICE_COL_NUM);
				for(var j:int = 0; j < GameGlobals.TOTAL_SLICE_COL_NUM; j++)
					tmpArray[j] = 0;
		
				_imageStatus.push(tmpArray);
			}	
			
			//初始化网格数组
			var totalGridColNum:int = Math.ceil(GameGlobals.TOTAL_SLICE_COL_NUM*GameGlobals.SLICE_WIDTH / gridWidth);
			var totalGridRowNum:int = Math.ceil(GameGlobals.TOTAL_SLICE_ROW_NUM*GameGlobals.SLICE_HEIGHT / gridHeight);
			grids = new Grid(totalGridColNum, totalGridRowNum);
			
			//初始化定点虚化信息
			alphaPointArray = new Array();
			for(i = 0; i < totalGridColNum; i++)
			{
				alphaPointArray[i] = new Array();
				for(j = 0; j < totalGridRowNum; j++)
				{
					alphaPointArray[i][j] = 0;
				}
			}			
		}
		
		//判断改切片是否已经在加载队列中
		private function IsAreadyIn(num:int):Boolean
		{
			for(var i:int=0; i< _imageToLoad.lenght; i++)
			{
				if(_imageToLoad[i] == num)
					return true;
			}
			
			return false;
		}
		
		//根据当前可视坐标，加载需要的地图切片
		private function getImagesToLoad():void
		{
			var halfColView:int = GameGlobals.VIEW_SLICE_ROW_NUM/2;
			var halfRowView:int =  GameGlobals.VIEW_SLICE_COL_NUM/2;
			
			var col:int = _viewPoint.x / GameGlobals.SLICE_WIDTH;
			var row:int = _viewPoint.y / GameGlobals.SLICE_HEIGHT;
					
			var num:int = row * GameGlobals.TOTAL_SLICE_COL_NUM + col;
			
			var colArray:Array = new Array();
			for(var i:int = col-halfColView; i<col+halfColView; i++)
			{
				colArray.push(i);	
			}
			
			//trace("colArray:"+colArray);
			
			if(colArray[0] < 0)
			{
				for(i = 0; i<colArray.length; i++)
				{
					colArray[i] += -colArray[0];	
				}			
			}
			
			if(colArray[colArray.length-1] > GameGlobals.TOTAL_SLICE_COL_NUM-1)
			{
				for(i = 0; i<colArray.length; i++)
				{
					colArray[i] -= colArray[colArray.length-1] - GameGlobals.TOTAL_SLICE_COL_NUM+1;	
				}			
			}			
			
			var rowArray:Array = new Array();
			for(i = row-halfRowView; i<row+halfRowView; i++)
			{
				rowArray.push(i);	
			}
			
			//trace("rowArray:"+rowArray);			
			
			if(rowArray[0] < 0)
			{
				for(i = 0; i<rowArray.length; i++)
				{
					rowArray[i] += -rowArray[0];	
				}			
			}
			
			if(rowArray[rowArray.length-1] > GameGlobals.TOTAL_SLICE_ROW_NUM-1)
			{
				for(i = 0; i<rowArray.length; i++)
				{
					rowArray[i] -= rowArray[rowArray.length-1] - GameGlobals.TOTAL_SLICE_ROW_NUM+1;	
				}			
			}						
			
			//trace("rowArray:"+rowArray);
			//trace("colArray:"+colArray);
			
			for(i=rowArray[0]; i<=rowArray[rowArray.length-1]; i++)
			{
				for(var j:int=colArray[0]; j<=colArray[colArray.length-1]; j++)
				{
					if(_imageStatus[i][j] == 0 && !IsAreadyIn(i*11 + j + 1))
					{
						_imageToLoad.push(i*11 + j + 1);
						_imageStatus[i][j] = 1;
					}
				}
			}	
			
			//if(_imageToLoad.length > 0)
				//trace(_imageToLoad)
		}
		
		private function getFileName(num:int):String
		{
			var str:String = "images\\RealMap_";
			
			var n:String = num.toString();
			if(n.length < 2)
			{
				n = "0"+ n;
			}
					
			//trace(str+n+".png");
			
			return str+n+".png";
		}
		
		private function LoadImages(num:int):void
		{	
			var imageLoader:Loader = new Loader();
			imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,
				imageLoadComplete);
			imageLoader.load(new URLRequest(getFileName(num)));	
			imageLoader.name = num.toString();
		}	
		
		
		private function imageLoadComplete(event:Event):void
		{	
			var num:int = parseInt((event.target as LoaderInfo).loader.name);
			//trace("load complete:"+num);
			
			var tmp:BitmapData = event.target.content.bitmapData;
			if(tmp != null)
			{
				_imagePos.x = ((num-1) % GameGlobals.TOTAL_SLICE_COL_NUM) * GameGlobals.SLICE_WIDTH;
				_imagePos.y = Math.floor((num-1)/GameGlobals.TOTAL_SLICE_COL_NUM) * GameGlobals.SLICE_HEIGHT;
				
				//trace("_imagePos.x:"+ _imagePos.x + "_imagePos.y:" + _imagePos.y)				
				
				bg.lock();
				bg.copyPixels(tmp, rect, _imagePos);
				bg.unlock();
				
				if(_imageToLoad.length > 0)
				{	
					LoadImages(_imageToLoad[_imageToLoad.length-1]);
					_imageToLoad.pop();
				}
			}			
		}		
		
		private function enterFrameHandler(event:Event):void
		{
						
		}		
	
		public function MoveTo(posX:Number, posY:Number):void
		{
			
			sceneRoot.x = stg.stageWidth/2 - posX;
			sceneRoot.y = stg.stageHeight/2 - posY;
			
			if(bBorderLimit)
			{
				if(posX - stg.stageWidth/2 < 0) //超过X坐标下界
				{
					sceneRoot.x = 0;
				}
				//超过X坐标上界
				else if(posX + stg.stageWidth/2 > GameGlobals.TOTAL_SLICE_COL_NUM * GameGlobals.SLICE_WIDTH)
				{
					sceneRoot.x = stg.stageWidth - GameGlobals.TOTAL_SLICE_COL_NUM * GameGlobals.SLICE_WIDTH;
				}
				
				if(posY - stg.stageHeight/2 < 0)//超过Y坐标下界
				{
					sceneRoot.y = 0;
				}
				//超过X坐标上界			
				else if(posY + stg.stageHeight/2 > GameGlobals.TOTAL_SLICE_ROW_NUM * GameGlobals.SLICE_HEIGHT)
				{
					sceneRoot.y =  stg.stageHeight - GameGlobals.TOTAL_SLICE_ROW_NUM * GameGlobals.SLICE_HEIGHT;
				}
			}
			//trace("sceneX:"+sceneRoot.x.toFixed(2)+",sceneY:"+sceneRoot.y.toFixed(2));	
			
			//更新可视中心点
			viewPoint.x = posX;
			viewPoint.y = posY;			
			
			//加载图片
			getImagesToLoad();
				
			if(_imageToLoad.length > 0)
			{
				//trace("Move status:" + _imageToLoad);
				
				LoadImages(_imageToLoad[_imageToLoad.length-1]);
				_imageToLoad.pop();
			}			
		}
		
		private function updateBlocks():void
		{				
			//阻挡点
			blocks.graphics.clear();
			blocks.graphics.lineStyle(1,0x00FFFF);
			blocks.graphics.beginFill(0xFF0000);			
			
			
			var totalGridRowNum:int = Math.ceil(GameGlobals.TOTAL_SLICE_ROW_NUM*GameGlobals.SLICE_HEIGHT / gridHeight);
			var totalGridColNum:int = GameGlobals.TOTAL_SLICE_COL_NUM*GameGlobals.SLICE_WIDTH / gridWidth;
			for(var i:int = 0; i < totalGridColNum; i++)
			{
				for(var j:int = 0; j < totalGridRowNum; j++)
				{
					if(!grids.getWalkable(i, j))
					{	
						blocks.graphics.moveTo(i*gridWidth, j*gridHeight);
						blocks.graphics.lineTo((i+1)*gridWidth, (j+1)*gridHeight);
						
						blocks.graphics.moveTo(i*gridWidth, (j+1)*gridHeight);
						blocks.graphics.lineTo((i+1)*gridWidth, j*gridHeight);					
					}	
				}
			}	
			
			blocks.graphics.endFill();	
			blocks.cacheAsBitmap = true;
		}
		
		//显示网格
		public function showMesh():void
		{
			if(mesh.parent == sceneRoot)
				return;			
			
			mesh.graphics.lineStyle(1,0xFF0000);			
			mesh.graphics.beginFill(0xFF0000);
			
			//横线
			for(var i:int = 0; i < GameGlobals.TOTAL_SLICE_ROW_NUM * GameGlobals.SLICE_HEIGHT / gridHeight; i++)
			{
				mesh.graphics.moveTo(0, (i+1)*gridHeight);
				mesh.graphics.lineTo(GameGlobals.TOTAL_SLICE_COL_NUM * GameGlobals.SLICE_WIDTH-1,
					(i+1)*gridHeight);
			}
			
			//竖线
			for(i = 0; i < GameGlobals.TOTAL_SLICE_COL_NUM * GameGlobals.SLICE_WIDTH / gridWidth; i++)
			{
				mesh.graphics.moveTo((i+1)*gridWidth, 0);
				mesh.graphics.lineTo((i+1)*gridWidth,
					GameGlobals.TOTAL_SLICE_ROW_NUM * GameGlobals.SLICE_HEIGHT-1);
			}
			
			mesh.graphics.endFill();
			mesh.cacheAsBitmap = true;
			
			sceneRoot.addChildAt(mesh, 1);
		}
		
		//隐藏
		public function hideMesh():void
		{
			if(mesh.parent == sceneRoot)
				sceneRoot.removeChild(mesh);	
		}
		
		public function showBlocks():void
		{
			if(blocks.parent == sceneRoot)
				return;
			
			updateBlocks();
			
			sceneRoot.addChildAt(blocks, 1);
		}
	
		public function hideBlocks():void
		{
			if(blocks.parent == sceneRoot)
				sceneRoot.removeChild(blocks);
		}		
		
		//获取阻挡点
		public function getBlocks():Array
		{
			var blks:Array = new Array();
			
			var totalGridRowNum:int = Math.ceil(GameGlobals.TOTAL_SLICE_ROW_NUM*GameGlobals.SLICE_HEIGHT / gridHeight);
			var totalGridColNum:int = GameGlobals.TOTAL_SLICE_COL_NUM*GameGlobals.SLICE_WIDTH / gridWidth;
			for(var i:int = 0; i < totalGridColNum; i++)
			{
				for(var j:int = 0; j < totalGridRowNum; j++)
				{
					if(!grids.getWalkable(i, j))
					{	
						blks.push(new Point(i, j));					
					}	
				}
			}			
			
			return blks;
		}
		//设置阻挡点
		public function setBlocks(blks:Array):void
		{
			for each (var pt:Point in blks)
			{
				grids.setWalkable(pt.x, pt.y, false);
			}
			
			//showBlocks();
		}
		
		public function isBlocked(x:Number, y:Number):Boolean
		{
			return !grids.getWalkable(Math.floor(x/gridWidth), Math.floor(y/gridHeight));
		}		
		
		public function updateAlphas():void
		{
			alphaPts.graphics.clear();
			alphaPts.graphics.lineStyle(1,0xFF00FF);
			alphaPts.graphics.beginFill(0xFF0000);			
			
			
			var totalGridRowNum:int = Math.ceil(GameGlobals.TOTAL_SLICE_ROW_NUM*GameGlobals.SLICE_HEIGHT / gridHeight);
			var totalGridColNum:int = GameGlobals.TOTAL_SLICE_COL_NUM*GameGlobals.SLICE_WIDTH / gridWidth;
			for(var i:int = 0; i < totalGridColNum; i++)
			{
				for(var j:int = 0; j < totalGridRowNum; j++)
				{
					if(alphaPointArray[i][j] != 0)
					{	
						alphaPts.graphics.moveTo(i*gridWidth+gridWidth/4, j*gridHeight);
						alphaPts.graphics.lineTo((i+1)*gridWidth-gridWidth/4, j*gridHeight+gridWidth/2);
						
						alphaPts.graphics.moveTo(i*gridWidth+gridWidth/4, j*gridHeight+gridWidth/2);
						alphaPts.graphics.lineTo((i+1)*gridWidth-gridWidth/4, j*gridHeight);					
					}	
				}
			}	
			
			alphaPts.graphics.endFill();	
			alphaPts.cacheAsBitmap = true;			
		}
		
		public function showAlphas():void
		{
			if(alphaPts.parent == sceneRoot)
				return;
			
			updateAlphas();
			
			sceneRoot.addChildAt(alphaPts, 1);
		}
		
		public function hideAlphas():void
		{
			if(alphaPts.parent == sceneRoot)
				sceneRoot.removeChild(alphaPts);
		}			
		
		//获取阻挡点
		public function getAlphas():Array
		{
			var alphas:Array = new Array();
			
			var totalGridRowNum:int = Math.ceil(GameGlobals.TOTAL_SLICE_ROW_NUM*GameGlobals.SLICE_HEIGHT / gridHeight);
			var totalGridColNum:int = GameGlobals.TOTAL_SLICE_COL_NUM*GameGlobals.SLICE_WIDTH / gridWidth;
			for(var i:int = 0; i < totalGridColNum; i++)
			{
				for(var j:int = 0; j < totalGridRowNum; j++)
				{
					if(alphaPointArray[i][j])
					{	
						alphas.push(new Point(i, j));					
					}	
				}
			}			
			
			return alphas;
		}
		//设置阻挡点
		public function setAlphas(alps:Array):void
		{
			for each (var pt:Point in alps)
			{
				alphaPointArray[pt.x][pt.y] = 1;
			}
			
			//showAlphas();
		}		
		
		public function isAlpha(x:Number, y:Number):Boolean
		{
			return alphaPointArray[Math.floor(x/gridWidth)][Math.floor(y/gridHeight)];
		}
		
		public function setStartPoint(x:Number, y:Number):void
		{
			grids.setStartNode(Math.floor(x/gridWidth), Math.floor(y/gridHeight));
		}
		
		public function setEndPoint(x:Number, y:Number):void
		{
			grids.setEndNode(Math.floor(x/gridWidth), Math.floor(y/gridHeight));		
		}
		
		public function findPath():Array
		{
			//A星寻路
			var astar:AStar = new AStar();
			if(astar.findPath(grids))
			{
				var p:Array = new Array();
				
				//逻辑坐标转化为像素坐标
				for each (var n:Node in astar.path)
				{
					var tmp:Node = new Node(0, 0);
					
					tmp.x = n.x * gridWidth + gridWidth / 2;
					tmp.y = n.y * gridHeight + gridHeight / 2;
					
					p.push(tmp);
				}
				
				return p;
			}

			return null;
		}
		
		private function mouseMoveHandler(event:MouseEvent):void
		{	
			if(event.ctrlKey == false)
				return;
			
			//逻辑坐标
			var logicX:uint = Math.floor(event.localX / gridWidth);
			var logicY:uint = Math.floor(event.localY / gridHeight);			
			
			if(lastLogicX != logicX || lastLogicY != logicY)
			{
				if(bSetBlock)
				{
					if(grids.getWalkable(logicX,logicY))
					{		
						grids.setWalkable(logicX,logicY, false);
						updateBlocks();
					}
					else
					{
						grids.setWalkable(logicX,logicY, true);
						updateBlocks();
					}				
				}
				
				lastLogicX = logicX;
				lastLogicY = logicY;
			}
		}		
		
		private function mouseUpHandler(event:MouseEvent):void
		{

		}		
		
		private function mouseDownHandler(event:MouseEvent):void
		{
			//trace("scene onMouseClick");
			
			//逻辑坐标
			var logicX:uint = Math.floor(event.localX / gridWidth);
			var logicY:uint = Math.floor(event.localY / gridHeight);			
			
			if(bSetBlock)
			{
				if(grids.getWalkable(logicX,logicY))
				{		
					grids.setWalkable(logicX,logicY, false);
					updateBlocks();
				}
				else
				{
					grids.setWalkable(logicX,logicY, true);
					updateBlocks();
				}				
			}	
			
			if(bSetAlpha)
			{
				if(alphaPointArray[logicX][logicY] == 0)
				{
					alphaPointArray[logicX][logicY] = 1;
					updateAlphas();
				}
				else
				{
					alphaPointArray[logicX][logicY] = 0;
					updateAlphas();
				}
			}
			
		}
	}
}

